submit choice Burj Khalifa - Dubai¶Taipei += 1 ✅¶Shanghai += 1 ✅¶Merdeka += 26 ❌¶Notes:
Asset Config Txn which specifies how the URL changes%%script false --no-raise-error
choice = Bytes(b"\x01") # "2. Burj Khalifa - Dubai
option_count_prefix = b"option_count_" # TODO: replace the option_count_keys[0] stuff below
new_choice_count_key = ScratchVar(TealType.bytes)
old_choice_count_key = ScratchVar(TealType.bytes)
submission_expr = Seq(
Assert(Btoi(choice) < Int(7)),
new_choice_count_key.store(
SetByte(option_count_keys[0], Int(len(option_count_prefix)), choice.get())
),
# ### BOXES BEGIN ### #
sender_box := App.box_get(Txn.sender()),
If(sender_box.hasValue()).Then(
# the sender has already submitted a response, so it must be cleared
Assert(App.globalGet(resubmit_key)),
old_choice_count_key.store(
SetByte(
option_count_keys[0],
Int(len(option_count_prefix)),
Btoi(sender_box.value()),
)
),
App.globalPut(
old_choice_count_key.load(),
App.globalGet(old_choice_count_key.load()) - Int(1),
),
),
App.box_put(Txn.sender(), choice.encode()),
# ### BOXES END ### #
App.globalPut(
new_choice_count_key.load(),
App.globalGet(new_choice_count_key.load()) + Int(1),
),
)
methods - allow interacting with Poll App¶delete for reasons to be explained shortly)¶OnComplete Actions for App Transactions¶| Value | Name | Description |
|---|---|---|
| 0 | NoOp | Execute ApprovalProgram only |
| 1 | OptIn | Allocate local state and execute ApprovalProgram |
| 2 | CloseOut | Execute ApprovalProgram and clear local state |
| 3 | ClearState | Execute ClearStateProgram and clear locals (even if rejects) |
| 4 | UpdateApplication | Execute ApprovalProgram and update programs |
| 5 | DeleteApplication | Execute ApprovalProgram and delete the app |
Router: Building an ARC-4 Application¶Router and its M.O.E. Questions¶Router and its M.O.E. Questions¶Router constructs the Teal code necessary to delegate application transactions to either a bare app call action or a method based on answers to:¶bare app call? If not, which method selected?¶OnComplete is requested?¶exists? (Conversely, being created?)¶Router: Building an ARC-4 Application¶Router Initialization¶
# WARNING: STUBS ARE FOR ROUTER-ILLUSTRATION PURPOSES ONLY!!!
del_action = OnCompleteAction.call_only(Seq())
router = Router(
name="OpenPollingApp",
descr="This is a polling application.",
bare_calls=BareCallActions(delete_application=del_action),
)
approval, clear, json_contract = router.compile_program(version=8)
JSON Contract (with no methods)¶print(json.dumps(json_contract.dictify(), indent=2))
{
"name": "OpenPollingApp",
"methods": [],
"networks": {},
"desc": "This is a polling application."
}
approval, clear, json_contract = router.compile_program(version=8)
print(approval)
#pragma version 8 txn NumAppArgs int 0 == bnz main_l2 err main_l2: txn OnCompletion int DeleteApplication == bnz main_l4 err main_l4: txn ApplicationID int 0 != assert int 1 return
delete¶show() # custom method showing relevant Teal
txn NumAppArgs
int 0
==
bnz main_l2
. . .
main_l2:
txn OnCompletion
int DeleteApplication
==
bnz main_l4
. . .
main_l4:
txn ApplicationID
int 0
!=
assert
int 1
return
methods to route with @router.method¶@router.method(name="open")
def open_poll() -> Expr:
"""Marks this poll as open."""
return Seq()
@router.method(name="close")
def close_poll() -> Expr:
"""Marks this poll as closed."""
return Seq()

approval, clear, json_contract = router.compile_program(version=8)
print(json.dumps(json_contract.dictify(), indent=2))
{
"name": "OpenPollingApp",
"methods": [
{
"name": "open",
"args": [],
"returns": {
"type": "void"
},
"desc": "Marks this poll as open."
},
{
"name": "close",
"args": [],
"returns": {
"type": "void"
},
"desc": "Marks this poll as closed."
}
],
"networks": {},
"desc": "This is a polling application."
}
open and close¶show()
txna ApplicationArgs 0
method "open()void"
==
bnz main_l5
. . .
txna ApplicationArgs 0
method "close()void"
==
bnz main_l4
. . .
main_l5:
txn OnCompletion
int NoOp
==
txn ApplicationID
int 0
!=
&&
assert
callsub open_0
. . .
main_l4:
txn OnCompletion
int NoOp
==
txn ApplicationID
int 0
!=
&&
assert
callsub close_1
. . .
// open
open_0:
retsub
. . .
// close
close_1:
retsub
PyTeal Type |
ARC-4 Type |
Dynamic / Static |
Description |
|---|---|---|---|
|
Static |
An 8-bit unsigned integer |
|
|
IFF |
A fixed-length array with N elements |
|
|
Dynamic |
Variable-length byte array |
@router.method
def submit(choice: abi.Uint8) -> Expr:
"""Submit a response to the poll.
Args:
choice: The choice made by the sender.
"""
return Seq()
opts = OptimizeOptions(scratch_slots=True)
approval, clear, json_contract = router.compile_program(version=8, optimize=opts)
# -----------------------------------------------------------------^^^^^^^^^^^^^
JSON Contract - method submit()¶show() # lines 20-33 of the JSON contract
{
"name": "submit",
"args": [
{
"type": "uint8",
"name": "choice",
"desc": "The choice made by the sender."
}
],
"returns": {
"type": "void"
},
"desc": "Submit a response to the poll."
}
submit(choice)¶show()
txna ApplicationArgs 0
method "submit(uint8)void"
==
bnz main_l5
. . .
main_l5:
txn OnCompletion
int NoOp
==
txn ApplicationID
int 0
!=
&&
assert
txna ApplicationArgs 1
int 0
getbyte
callsub submit_2
. . .
// submit
submit_2:
store 0
retsub
show()
def on_delete() -> Expr:
return Assert(Txn.sender() == Global.creator_address())
router = Router(
name="OpenPollingApp",
descr="A polling application with no restrictions on who can participate.",
bare_calls=BareCallActions(
delete_application=OnCompleteAction.call_only(on_delete())
),
)
open_key = Bytes(b"open")
resubmit_key = Bytes(b"resubmit")
option_name_prefix = b"option_name_"
option_name_keys = [
Bytes(option_name_prefix + b"